Skip to content

Enable HACS zip_release packaging with validated release asset#74

Merged
eXPerience83 merged 9 commits intomainfrom
codex/enable-hacs-download-counter-with-zip-asset
Feb 24, 2026
Merged

Enable HACS zip_release packaging with validated release asset#74
eXPerience83 merged 9 commits intomainfrom
codex/enable-hacs-download-counter-with-zip-asset

Conversation

@eXPerience83
Copy link
Owner

@eXPerience83 eXPerience83 commented Feb 23, 2026

User description

Motivation

  • Provide HACS with a stable GitHub Release ZIP asset so HACS can display download counts and install releases reliably.
  • Ensure release packaging will not break HACS/HA installs by validating the ZIP structure before upload.

Description

  • Add "zip_release": true and "filename": "pollenlevels.zip" to hacs.json to enable release-asset installs.
  • Add .github/workflows/release.yml which runs on release: types: [published], builds pollenlevels.zip containing custom_components/pollenlevels/**, validates that custom_components/pollenlevels/manifest.json and __init__.py exist and that all entries start with custom_components/, and uploads/overwrites the asset using softprops/action-gh-release@v2.
  • Add .github/workflows/package-test.yml which is workflow_dispatch only, builds and validates the same ZIP, and uploads it as a CI artifact via actions/upload-artifact@v4 for pre-release verification.
  • Keep integration code and runtime behavior unchanged; changes are limited to release packaging configuration and workflows.

Testing

  • Ran ruff check --fix --select I . and ruff check ., both completed with no errors.
  • Ran black . formatting, which completed successfully.
  • Performed a local packaging smoke test by running zip -r pollenlevels.zip custom_components/pollenlevels and asserting inside Python that required paths exist and all zip entries start with custom_components/, and the script printed ok indicating validation passed.

Codex Task


PR Type

Enhancement


Description

  • Add HACS zip_release support with validated ZIP packaging workflows

  • Create release workflow that builds and uploads ZIP asset on publish

  • Create package-test workflow for pre-release ZIP validation

  • Implement ZIP structure validation ensuring integration-root layout

  • Update version to 1.9.4 and document packaging changes


Diagram Walkthrough

flowchart LR
  A["Release Published"] -->|"triggers"| B["release.yml"]
  B -->|"builds"| C["pollenlevels.zip"]
  C -->|"validates"| D["ZIP Structure Check"]
  D -->|"uploads"| E["GitHub Release Asset"]
  F["Manual Dispatch"] -->|"triggers"| G["package-test.yml"]
  G -->|"builds"| H["pollenlevels.zip"]
  H -->|"validates"| I["ZIP Structure Check"]
  I -->|"uploads"| J["CI Artifact"]
  K["hacs.json"] -->|"enables"| L["zip_release mode"]
Loading

File Walkthrough

Relevant files
Enhancement
release.yml
Release workflow for HACS ZIP asset upload                             

.github/workflows/release.yml

  • New workflow triggered on GitHub release publication
  • Builds pollenlevels.zip from integration root directory
  • Validates ZIP structure with Python script checking for required files
    and correct layout
  • Uploads ZIP to release asset with overwrite and strict failure on
    missing files
+61/-0   
package-test.yml
Package test workflow for ZIP validation                                 

.github/workflows/package-test.yml

  • New manual workflow for pre-release ZIP validation
  • Builds and validates ZIP structure identically to release workflow
  • Uploads validated ZIP as CI artifact for testing
  • Uses least-privilege permissions with read-only contents access
+58/-0   
Configuration changes
hacs.json
Enable HACS zip_release configuration                                       

hacs.json

  • Enable zip_release mode for HACS integration
  • Specify pollenlevels.zip as the release asset filename
  • Allows HACS to display download counts and manage installations
+3/-1     
manifest.json
Update integration version number                                               

custom_components/pollenlevels/manifest.json

  • Bump version from 1.9.3 to 1.9.4
+1/-1     
pyproject.toml
Update project version number                                                       

pyproject.toml

  • Bump project version from 1.9.3 to 1.9.4
+1/-1     
Documentation
CHANGELOG.md
Document version 1.9.4 release changes                                     

CHANGELOG.md

  • Add version 1.9.4 release notes dated 2026-02-24
  • Document release packaging automation updates for HACS zip_release
  • Note ZIP validation, strict upload failure, and artifact action
    upgrade
+7/-0     

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @eXPerience83, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on improving the release packaging process for the 'Pollen Levels' custom component to ensure compatibility and reliable installation via HACS. It introduces automated workflows for building, validating, and publishing the component as a ZIP archive, enhancing the user experience and simplifying the installation process.

Highlights

  • HACS Integration: This PR enables HACS (Home Assistant Community Store) to reliably install releases and display download counts by providing a stable GitHub Release ZIP asset.
  • Release Packaging: It introduces a new release workflow that builds and validates a ZIP file containing the custom component, ensuring it meets HACS requirements before being uploaded as a release asset.
  • Validation Workflow: A package-test workflow was added to pre-release verification by building, validating, and uploading the ZIP as a CI artifact.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/package-test.yml
    • .github/workflows/release.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates hacs.json to enable zip_release packaging for HACS. The changes are straightforward, but I've found one issue regarding JSON formatting. A trailing comma has been added, which makes the JSON invalid according to the strict standard and could cause issues with some parsers. I've left a specific comment with a suggestion to fix this.

@eXPerience83 eXPerience83 self-assigned this Feb 23, 2026
@eXPerience83 eXPerience83 marked this pull request as ready for review February 24, 2026 14:20
@qodo-code-review
Copy link
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Unpinned GitHub Actions

Description: The workflow uses third-party GitHub Actions by mutable tags (e.g., actions/checkout@v6
and softprops/action-gh-release@v2) instead of pinning to immutable commit SHAs, which
creates a supply-chain risk if an upstream tag is moved or compromised, especially with
contents: write permissions.
release.yml [16-60]

Referred Code
  uses: actions/checkout@v6

- name: Build release ZIP (integration root at ZIP root)
  shell: bash
  run: |
    set -euo pipefail
    rm -f "${{ github.workspace }}/pollenlevels.zip"
    cd "${{ github.workspace }}/custom_components/pollenlevels"
    zip "${{ github.workspace }}/pollenlevels.zip" -r ./

- name: Validate ZIP structure (zip_release-compatible)
  shell: bash
  run: |
    set -euo pipefail
    python - <<'PY'
    import zipfile

    zip_path = "pollenlevels.zip"
    required = {"manifest.json", "__init__.py"}

    with zipfile.ZipFile(zip_path) as zf:


 ... (clipped 24 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
fix zip path entries

Change the zip command from zip -r ./ to zip -r ./* to prevent a leading ./
prefix in archive paths, which would break the validation step.

.github/workflows/package-test.yml [22]

-zip "${{ github.workspace }}/pollenlevels.zip" -r ./
+zip "${{ github.workspace }}/pollenlevels.zip" -r ./*
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: This suggestion fixes a critical bug where the zip command would create file paths with a ./ prefix, causing the subsequent Python validation step to fail.

High
General
enable integration-root ZIP in HACS

Set content_in_root to true in hacs.json to align with the new ZIP structure and
ensure correct installation by HACS.

hacs.json [4]

-"content_in_root": false,
+"content_in_root": true,
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: This suggestion fixes a critical configuration error in hacs.json that would cause HACS to install the integration incorrectly, as the PR changes the package structure to be at the zip root.

High
High-level
Refactor duplicated workflow logic into a reusable composite action

Extract the duplicated build and validation logic from release.yml and
package-test.yml into a reusable composite GitHub Action to improve
maintainability and avoid inconsistencies.

Examples:

.github/workflows/package-test.yml [16-52]
      - name: Build release ZIP (integration root at ZIP root)
        shell: bash
        run: |
          set -euo pipefail
          rm -f "${{ github.workspace }}/pollenlevels.zip"
          cd "${{ github.workspace }}/custom_components/pollenlevels"
          zip "${{ github.workspace }}/pollenlevels.zip" -r ./

      - name: Validate ZIP structure (zip_release-compatible)
        shell: bash

 ... (clipped 27 lines)
.github/workflows/release.yml [18-54]
      - name: Build release ZIP (integration root at ZIP root)
        shell: bash
        run: |
          set -euo pipefail
          rm -f "${{ github.workspace }}/pollenlevels.zip"
          cd "${{ github.workspace }}/custom_components/pollenlevels"
          zip "${{ github.workspace }}/pollenlevels.zip" -r ./

      - name: Validate ZIP structure (zip_release-compatible)
        shell: bash

 ... (clipped 27 lines)

Solution Walkthrough:

Before:

# In .github/workflows/package-test.yml
jobs:
  package:
    steps:
      - uses: actions/checkout@v6
      - name: Build release ZIP
        run: |
          # ... build logic ...
      - name: Validate ZIP structure
        run: |
          # ... validation logic ...
      - uses: actions/upload-artifact@v6

# In .github/workflows/release.yml
jobs:
  package-and-upload:
    steps:
      - uses: actions/checkout@v6
      - name: Build release ZIP
        run: |
          # ... identical build logic ...
      - name: Validate ZIP structure
        run: |
          # ... identical validation logic ...
      - uses: softprops/action-gh-release@v2

After:

# In .github/actions/build-and-validate/action.yml (new file)
name: 'Build and Validate Package'
runs:
  using: 'composite'
  steps:
    - name: Build release ZIP
      shell: bash
      run: |
        # ... build logic ...
    - name: Validate ZIP structure
      shell: bash
      run: |
        # ... validation logic ...

# In .github/workflows/package-test.yml & release.yml
jobs:
  ...
    steps:
      - uses: actions/checkout@v6
      - uses: ./.github/actions/build-and-validate
      - name: Upload artifact/release asset
        uses: ...
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies significant code duplication between the release.yml and package-test.yml workflows, and proposing a composite action is an excellent way to improve maintainability.

Medium
  • More

@eXPerience83 eXPerience83 merged commit 38a3283 into main Feb 24, 2026
9 checks passed
@eXPerience83 eXPerience83 deleted the codex/enable-hacs-download-counter-with-zip-asset branch February 24, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant